package com.example.observe.events.core;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 事件监听器
 */
public class EventListener {

    // 保存定义的事件
    protected Map<String, Event> events = new HashMap<>();


    public void addListener(String eventType, Object target) {
        try {
            /* 这里的 this 是 Mouse 对象，在 Mouse 上面添加 eventType 类型的监听事件
               并把事件通知的对象这里是 MouseCallback 设置到 Event 的 target 属性中，当触发事件的时候通知该对象，是通过反射调用这个对象对应的方法
               并通过反射获取到事件需要执行的方法
             */
            this.addListener(eventType, target,
                    target.getClass().getMethod("on" + toUpperFirstCase(eventType), Event.class));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public void addListener(String eventType, Object target, Method method) {
        events.put(eventType, new Event(target, method));
    }

    /**
     * 触发，根据事件触发
     *
     * @param event 触发的事件
     */
    public void trigger(Event event) {

        // 这里的 this 是 Mouse 对象，因为 trigger 方法是在 Mouse 类中通过 this 调用
        event.setSource(this);
        event.setTime(System.currentTimeMillis());

        try {
            if (event.getCallBack() != null) {
                event.getCallBack().invoke(event.getTarget(), event);
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据事件类型触发
     *
     * @param eventType 时间类型
     */
    public void trigger(String eventType) {
        if (!this.events.containsKey(eventType)) {
            return;
        }
        trigger(this.events.get(eventType).setTrigger(eventType));
    }

    //逻辑处理的私有方法，首字母大写
    private String toUpperFirstCase(String str) {
        char[] chars = str.toCharArray();
        chars[0] -= 32;
        return String.valueOf(chars);
    }

}
